import type { Logger } from 'drizzle-orm';

/**
 * 自定义 SQL Logger
 *
 * 使用彩色输出美化 SQL 日志，支持：
 * - 彩色输出（开发环境）
 * - SQL 语句高亮
 * - 参数格式化
 * - 可配置开关
 */
export class SqlLogger implements Logger {
  // ANSI 颜色代码
  private readonly colors = {
    reset: '\x1b[0m',
    cyan: '\x1b[36m',
    yellow: '\x1b[33m',
    green: '\x1b[32m',
    gray: '\x1b[90m',
    blue: '\x1b[34m',
  };

  private enabled: boolean;

  constructor(enabled = true) {
    this.enabled = enabled;
  }

  /**
   * 记录 SQL 查询
   *
   * @param query SQL 查询语句
   * @param params 查询参数
   */
  logQuery(query: string, params: unknown[]): void {
    // 如果未启用，直接返回
    if (!this.enabled) {
      return;
    }

    const timestamp = this.formatTimestamp();
    const formattedParams = this.formatParams(params);

    console.log(
      `${this.colors.gray}[${timestamp}]${this.colors.reset} ` +
      `${this.colors.blue}🔍 Drizzle SQL Query${this.colors.reset}`
    );
    console.log(`${this.colors.cyan}SQL:${this.colors.reset}`);
    console.log(`  ${query}`);
    console.log(`${this.colors.yellow}Params:${this.colors.reset} ${formattedParams}`);
    console.log('');
  }

  /**
   * 格式化时间戳
   */
  private formatTimestamp(): string {
    const now = new Date();
    const year = now.getFullYear();
    const month = String(now.getMonth() + 1).padStart(2, '0');
    const day = String(now.getDate()).padStart(2, '0');
    const hours = String(now.getHours()).padStart(2, '0');
    const minutes = String(now.getMinutes()).padStart(2, '0');
    const seconds = String(now.getSeconds()).padStart(2, '0');
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  }

  /**
   * 格式化参数
   * 将参数转换为易读的格式
   */
  private formatParams(params: unknown[]): string {
    if (params.length === 0) {
      return '[]';
    }

    return params.map((param, index) => {
      let value: string;

      if (param === null) {
        value = 'NULL';
      } else if (param === undefined) {
        value = 'UNDEFINED';
      } else if (typeof param === 'string') {
        value = `'${param}'`;
      } else if (param instanceof Date) {
        value = `'${param.toISOString()}'`;
      } else if (typeof param === 'object') {
        value = JSON.stringify(param);
      } else {
        value = String(param);
      }

      return `$${index + 1}=${value}`;
    }).join(', ');
  }
}

